<script lang="ts">
import { defineComponent, ref, h, onMounted } from "vue";
import { ElInput, ElSelect, ElOption } from "element-plus";
import type { VNode } from "vue";
import type { nodeItem } from "../index.d";
// import { NodeTree } from "../index.vue";
import { Plus, Minus, CircleCheck, CircleClose } from "@element-plus/icons-vue";
import { ElIcon } from "element-plus";
import { computed } from "vue";

interface strategyData {
  [key: string]: (item: nodeItem) => VNode | VNode[];
}

export default defineComponent({
  name: "NodeValue",
  props: {
    data: {
      type: Object as () => nodeItem,
      required: true
    },
    readonly: {
      type: Boolean,
      required: true
    }
  },
  setup(props, context) {
    const isHasFocus = ref(false);
    const validText = ref("");
    const checkText = ref("");
    const validTypeArr = ["Integer", "BitString", "NumericString", "Ia5string", "OctetString", "String"];
    const otherProps = computed(() => {
      return props.data.bitArray ? props.data.bitArray.map((x) => (x ? 1 : 0)).join("") : "";
    });
    // 公共表单验证
    const formValid = (data: nodeItem) => {
      if (data.isRequired && data.value === "") {
        validText.value = "字段必填";
        return;
      }
      if (data.controlType === "Integer") {
        const { minInclusive, maxInclusive, value } = data;
        if (!minInclusive && !maxInclusive) {
          checkText.value = validText.value = "";
          return;
        }
        if (Number(value) < minInclusive) {
          validText.value = `最小值为${minInclusive}`;
          return;
        }
        if (Number(value) > maxInclusive) {
          validText.value = `最大值为${maxInclusive}`;
          return;
        }
      } else if (data.controlType === "BitString") {
        const { Length } = data;
        checkText.value = `长度为${Length}的二进制数`;
        if (otherProps.value.length !== Length) {
          validText.value = `长度应为${Length}`;
          return;
        }
      }
      validText.value = "";
    };
    const updateEmit = () => {
      if (validText.value === "") {
        context.emit("updateForm", props.data);
      }
    };

    // 公共事件
    const publicEvent = {
      onfocus: () => {
        isHasFocus.value = true;
      },
      onblur: () => {
        isHasFocus.value = false;
      }
    };

    onMounted(() => {
      // console.log("props.data.ControlType", props.data.ControlType);
    });

    // 渲染策略
    const strategy: strategyData = {
      Integer: (data: nodeItem) => {
        const { value, isReadOnly: disabled } = data;
        return h(ElInput, {
          class: ["int-input", "el-input"], // 保持原有类名 + 组件基础类
          modelValue: value as number, // 双向绑定值
          readonly: props.readonly,
          disabled,
          "onUpdate:modelValue": (val) => {
            // 确保值更新同步
            data.value = val;
            formValid(data);
          },
          onChange: (val) => {
            if (!value) return;
            data.value = parseFloat(val);
            updateEmit();
          },
          ...publicEvent
        });
      },
      Ia5string: (data: nodeItem) => {
        const { value: value, minLength, isReadOnly: disabled } = data;
        return h(ElInput, {
          class: ["int-input", "el-input"], // 保持原有类名 + 组件基础类
          modelValue: value as string, // 双向绑定值
          readonly: props.readonly,
          "onUpdate:modelValue": (val) => {
            // 确保值更新同步
            data.value = val;
            formValid(data);
          },
          onChange: () => {
            updateEmit();
          },
          ...publicEvent
        });
      },
      String: (data: nodeItem) => {
        const { value: value, minLength, isReadOnly: disabled } = data;
        return h(ElInput, {
          class: ["int-input", "el-input"], // 保持原有类名 + 组件基础类
          modelValue: value as string, // 双向绑定值
          readonly: props.readonly,
          "onUpdate:modelValue": (val) => {
            // 确保值更新同步
            data.value = val;
            formValid(data);
          },
          onChange: () => {
            updateEmit();
          },
          ...publicEvent
        });
      },
      OctetString: (data: nodeItem) => {
        const { value: value, minLength, isReadOnly: disabled } = data;
        return h(ElInput, {
          class: ["int-input", "el-input"],
          modelValue: value as string, // 双向绑定值
          readonly: props.readonly,
          attrs: { minlength: minLength, readonly: props.readonly },
          "onUpdate:modelValue": (val) => {
            // 确保值更新同步
            data.value = val;
            formValid(data);
          },
          onChange: (val) => {
            const is16Hex = /^[\-A-Fa-f0-9\s]*$/.test(val);
            if (is16Hex) {
              const newValue = value !== "" ? (String(value).replace(/\s+/g, "").match(new RegExp("[^\\n]{1,2}", "g")) as string[]).join(" ") : "";
              data.value = newValue;
              formValid(data);
              updateEmit();
            }
          }
        });
      },
      // NumericString: (data: nodeItem) => {
      //   const { Value: value, MinLength, IsReadOnly: disabled } = data;
      //   return h("el-input", {
      //     class: "int-input",
      //     props: { value, disabled },
      //     attrs: { minlength: MinLength, readonly: props.readonly },
      //     on: {
      //       input: (value: string) => {
      //         const isNumber = /^[\.\-0-9]*$/.test(value);
      //         if (isNumber) {
      //           data.Value = value;
      //           formValid(data);
      //         }
      //       },
      //       ...publicEvent,
      //     },
      //   });
      // },
      // BitString: (data: nodeItem) => {
      //   const { IsReadOnly: disabled } = data;
      //   const { value } = otherProps;
      //   return h("el-input", {
      //     class: "int-input",
      //     props: { otherProps.value.value, disabled },
      //     attrs: { readonly: props.readonly },
      //     on: {
      //       input: (value: string) => {
      //         const isBinary = /^[0|1]*$/.test(value);
      //         if (isBinary) {
      //           data.OtherProps = value;
      //           formValid(data);
      //         }
      //       },
      //       change: (value: string) => {
      //         data.BitArray = value.split("").map(x => !!Number(x));
      //       },
      //       ...publicEvent,
      //     },
      //   });
      // },
      Enum: (data: nodeItem) => {
        const { value: value, constraint, isReadOnly: disabled } = data;

        const options = [] as any[];

        constraint?.forEach((optionValue) => {
          options.push({ label: optionValue, value: optionValue });
        });

        return h(
          ElSelect,
          {
            class: "custom-el-select", // 添加自定义类名
            modelValue: data.value,
            "onUpdate:modelValue": (val) => {
              data.value = val;
            },
            onChange: () => {
              updateEmit();
            },
            size: "small"
          },
          [
            ...options.map((option) =>
              h(ElOption, {
                key: option.value,
                label: option.label,
                value: option.value
              })
            )
          ]
        );
      },
      // Choice: (data: nodeItem) => {
      //   const { Value: value, Constraint, IsReadOnly: disabled } = data;
      //   const optionsArr = Constraint.map(value => {
      //     if (typeof value === "string") return;
      //     return h("el-option", { props: { label: value.Name, value } });
      //   });
      //   return h(
      //     "el-select",
      //     {
      //       class: "enum-select",
      //       props: { value, valueKey: "Name", placeholder: " ", disabled: disabled || props.readonly },
      //       on: {
      //         input: (value: string) => {
      //           data.Value = value;
      //         },
      //       },
      //     },
      //     [optionsArr],
      //   );
      // },
      Boolean: (data: nodeItem) => {
        const options = [
          { label: "是", value: true },
          { label: "否", value: false }
        ];

        return h(
          ElSelect,
          {
            class: "custom-el-select", // 添加自定义类名
            modelValue: data.value,
            "onUpdate:modelValue": (val) => {
              data.value = val;
            },
            onChange: () => {
              updateEmit();
            },
            size: "small"
          },
          [
            ...options.map((option) =>
              h(ElOption, {
                label: option.label,
                value: option.value
              })
            )
          ]
        );
      },
      Sequence: () => {
        return h("div", {}, ""); // Render an empty div as a placeholder
      },
      SequenceList: (data: nodeItem) => {
        const max = 9999;
        const min = 0;
        const len = data.child && data.child.length;
        const elementName = "成员";
        // const validText = `下级${min}~${max}组数据` ;
        return h("div", { class: "sequence-list-value" }, [
          h(
            "div",
            {
              class: "btn-icon"
            },
            [
              h(
                ElIcon,
                {
                  class: `el-icon-plus ${len < max ? "" : "gray"}`,
                  onClick: () => {
                    if (len < max) {
                      // const addRow = data.Child[len - 1];
                      const addRow = data.elementForm;
                      const count = data.child ? data.child.length + 1 : 1;
                      if (addRow) {
                        addRow.name = `${elementName}(${count})`;
                      }
                      data.child.push(JSON.parse(JSON.stringify(addRow)));
                      updateEmit();
                    }
                  }
                },
                [h(Plus)]
              ),
              h(
                ElIcon,
                {
                  class: `el-icon-minus ${len > min ? "" : "gray"}`,
                  onClick: () => {
                    if (len > min) {
                      data.child.pop();
                      updateEmit();
                    }
                  }
                },
                [h(Minus)]
              )
            ]
          )
          // h("span", { class: "valid-text" }, validText),
        ]);
      },
      // 其他控件类型的渲染逻辑...
      default: (data: nodeItem) => {
        return h("div", {}, `未定义的控件类型: ${data.controlType}`);
      }
    };

    formValid(props.data);

    return () => {
      return h(
        "div",
        {
          class: {
            "node-value": true,
            "node-valid-error": validText.value
          }
        },
        [
          (strategy[props.data.controlType] || strategy.default)(props.data),
          validTypeArr.includes(props.data.controlType) &&
            h("span", { class: "valid-icon" }, [
              [
                validText.value
                  ? h(ElIcon, { color: "red", size: 16 }, [h(CircleClose)])
                  : isHasFocus.value && !props.readonly && h(ElIcon, { color: "#67c23a", size: 16 }, [h(CircleCheck)])
              ],
              isHasFocus.value && validText.value && h("div", { class: "valid-tips err" }, validText.value),
              !validText.value && !props.readonly && isHasFocus.value && checkText.value && h("div", { class: "valid-tips" }, checkText.value)
            ])
        ]
      );
    };
  }
});
</script>

<style lang="scss" scoped>
.node-value {
  position: relative;
  width: 100%;
  height: 100%;

  > div {
    width: 100%;
    height: 100%;
  }

  :deep(.el-input .el-input__wrapper) {
    height: 100%;
    border: 0;
    box-shadow: none;
    background-color: transparent;
    height: 100%;
    display: block;
    padding: 0 12px;
    text-align: left;
    font-size: 12px;
    border-radius: 0;

    .el-input__inner {
      color: #616575 !important;
    }

    &::-webkit-outer-spin-button,
    &::-webkit-inner-spin-button {
      -webkit-appearance: none;
    }

    &:focus {
      + .el-input__suffix .el-input__count {
        opacity: 1;
      }
    }

    &:disabled {
      background: #616575;
    }

    .el-input__icon {
      line-height: 30px;
    }

    .el-input__count {
      opacity: 0;
    }
  }

  :deep(.int-input) {
    --el-input-height: 29px;
    .el-input-number__increase,
    .el-input-number__decrease {
      display: none;
    }
    .el-input__inner {
      --el-input-inner-height: 29px;
    }
  }

  :deep(.enum-select) {
    .el-select__caret {
      &:before {
        content: "\e78f";
      }
    }
  }
  :deep(.custom-el-select) {
    .el-select__wrapper {
      --el-border-color: transparent;
      --el-border-color-hover: transparent;
      min-height: 100%;
      padding: 0 12px;
    }
  }

  .ia5string-input {
    padding: 0 12px;
    display: flex;
    align-items: center;
    box-sizing: border-box;
    overflow: hidden;
  }

  .valid-icon {
    position: absolute;
    right: 0;
    top: 8px;
    padding-right: 10px;

    .valid-tips {
      background: #303133;
      color: #fff;
      position: absolute;
      right: 0;
      top: 23px;
      border-radius: 4px;
      padding: 5px;
      z-index: 2000;
      font-size: 12px;
      line-height: 1.2;
      min-width: 10px;
      word-break: keep-all;

      &::after {
        position: absolute;
        display: block;
        width: 0;
        height: 0;
        border-color: transparent;
        border-style: solid;
        content: " ";
        border-width: 5px;
        border-bottom-color: #303133;
        top: -10px;
        right: 12px;
      }
    }
  }

  .sequence-list-value {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .btn-icon {
      flex: 1;
      font-size: 14px;
      display: flex;
      align-items: center;
      justify-content: center;

      i {
        cursor: pointer;
        margin: 0 20px;
        font-weight: bold;
      }

      .el-icon-plus {
        color: #3a6ef6;

        &.gray {
          color: #999;
        }
      }

      .el-icon-minus {
        color: #eb5757;

        &.gray {
          color: #999;
        }
      }
    }

    .valid-text {
      font-size: 12px;
      color: #666666;
      padding-right: 10px;
    }
  }
}
</style>
